const router = require("express").Router();
const config = require("../config");
const FS = require("fs");
const { resolve, normalize } = require("path");
const md5 = require("md5");
const Api = require("../utils");
const db = require('../schema');
Api.md5 = md5;
const paths = [];
function getRoutes(path, name) {
  path = resolve(path, name);
  let dir = FS.readdirSync(path);
  dir.forEach(e => {
    if (FS.statSync(resolve(path, e)).isDirectory()) getRoutes(path, e);
    if (/^(post|get|put|delete|index)(\.js)$/.test(e)) {
      paths.push({
        filePath: resolve(path, e),
        path: normalize(resolve(path, e)).replace(normalize(config.rootSrc), '').replace(e, '').replace(/\\/g, '/').replace(/\/$/, ''),
        method: e.replace('.js', '').replace('index', 'all'),
        handler: require(resolve(path, e)),
        name: e,
        doc: require(resolve(path, e)).doc || ''
      });
    }
  });
}
getRoutes(config.rootSrc, 'api');
router.use((req, res, next) => {
  res.header({
    "Access-Control-Allow-Origin": req.headers.origin,
    "Access-Control-Allow-Method": "GET,POST,PUT,DELETE,OPTIONS",
    "Access-Control-Allow-Credentials": true,
    "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, token",
    "Access-Control-Max-Age": "10000",
  });
  // 预检请求返回
  if (req.method.toLowerCase() === "options") {
    res.sendStatus(200);
    return;
  }
  // 设置操作日志
  res.setlog = function (data) {
    return this.ApiLog.setlog.bind(this)(req, data);
  };
  res.error = function (code) {
    let text = config.error[code];
    this.status(code).send({ code, message: text });
  };
  res.info = function (data) {
    if (data && data.log) {
      this.setlog(data.log)
        .then(() => {
          typeof data === "object" ? (data = { ...data }) : "";
          delete data.log;
          this.status(400).send({ code: 400, message: data });
        })
        .catch((err) => {
          console.log(err);
          console.log("Error: ", __dirname);
          typeof data === "object" ? (data = { ...data }) : "";
          delete data.log;
          this.status(400).send({
            code: 400,
            message: data,
            log: "日志记录写入失败",
          });
        });
    } else {
      this.status(400).send({ code: 400, message: data });
    }
  };
  res.success = function (data) {
    if (data && data.log) {
      this.setlog(data.log)
        .then(() => {
          typeof data === "object" ? (data = { ...data }) : "";
          delete data.log;
          this.status(200).send({ code: 200, message: "ok", data });
        })
        .catch((err) => {
          console.log(err);
          console.error("Error: ", __dirname);
          delete data.log;
          typeof data === "object" ? (data = { ...data }) : "";
          this.status(200).send({
            code: 200,
            message: "请求处理完成，日志记录写入失败",
            data,
          });
        });
    } else {
      typeof data === "object" ? (data = { ...data }) : "";
      this.status(200).send({ code: 200, message: "ok", data });
    }
  };
  next();
});

// 验证请求Token
router.use((req, res, next) => {
  // 验证公共请求token
  if (req.method.toLowerCase() !== "get" && req.headers.token !== "token") {
    console.log("******************");
    res.error(401);
    return;
  }
  // 验证私密请求token
  if (/(\/user|\/manage)/.test(req.url)) {
    // 获取cookie
    let token = req.headers.cookie || "";
    let cookies = {};
    let arr = token ? token.split("; ") : [];
    arr.forEach((e) => {
      cookies[e.split("=")[0]] = e.split("=")[1];
    });
    if (!arr.length) {
      res.error(403);
      return;
    }
    Api.ApiDb.find(
      {
        table: config.db.table.token,
        find: { token: cookies.user_token },
      },
      (err, data) => {
        if (!err && data.length > 0 && data[0].maxAge > Date.now()) {
          if (data[0].maxAge < Date.now() + 4 * 24 * 60 * 60 * 1000) {
            Api.ApiDb.update({
              table: config.db.table.token,
              find: { token: cookies.user_token },
              value: { maxAge: Date.now() + 24 * 7 * 60 * 60 * 1000 },
            });
          }
          res.userInfo = data.user;
          next();
        } else {
          res.info("user_token验证不通过");
          return;
        }
      }
    );
  } else {
    next();
  }
});

paths.forEach(item => {
  router[item.method](item.path, function (req, res, next) {
    try {
      if (typeof item.handler == 'function') item.handler({ req, res, config, api: Api, db });
      else if (typeof item.handler == 'object') item.handler[req.method.toLowerCase()]({ req, res, config, api: Api, db });
      else next()
    } catch (error) {
      next()
    }
  })
});
// 路由不存在
router.all("*", (req, res) => {
  res.error(503);
});
module.exports = paths;
